﻿using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using LitJson;

[AddComponentMenu("PUEX/Affector/Velocity/DirectionOverLifetime")]
public class PUEXDirectionOverLifetimeAffector : PUEXAffector {

	public enum DirectionMode {
		DM_Add,
		DM_Multi,
	}

	#region - Editable property
	public DirectionMode directionMode;
	public PUEXDynamicAttribute directionX;
	public PUEXDynamicAttribute directionY;
	public PUEXDynamicAttribute directionZ;
	public bool useEmitterTime;
	public bool inWorldSpace;
	#endregion
	
	#region - Lifecycle
	public PUEXDirectionOverLifetimeAffector ()
	{
		directionMode = DirectionMode.DM_Add;
		directionX = PUEXDynamicAttribute.GenerateFixed(1f);
		directionY = PUEXDynamicAttribute.GenerateFixed(1f);
		directionZ = PUEXDynamicAttribute.GenerateFixed(1f);
		useEmitterTime = false;
		inWorldSpace = true;
	}
	#endregion
	
	#region - Update
	public override void update (float dt, PUEXParticle particle)
	{
		float t = particle.timeFraction;
		if (useEmitterTime)
			t = inTrigger () ? triggerTimeFraction : ownerEmitter.timeFraction;

		Vector3 newDirection = new Vector3 (directionX.getValue(t),
		                                     directionY.getValue(t),
		                                     directionZ.getValue(t));
		if (inWorldSpace) {
			if (ownerEmitter.keepLocal) {
				Matrix4x4 invMat = ownerEmitter.ownerParticleSystem.systemToWorldTransform.inverse;
				newDirection = invMat.MultiplyVector(newDirection);
			}
		} else {
			if (!ownerEmitter.keepLocal) {
				newDirection = ownerEmitter.ownerParticleSystem.systemToWorldTransform.MultiplyVector(newDirection);
			}
		}

		switch (directionMode) {
		case DirectionMode.DM_Add: {
			particle.direction = (particle.direction + newDirection * dt).normalized;
			break;
		}
		case DirectionMode.DM_Multi: {
			particle.direction = Vector3.Scale (particle.originalDirection, newDirection).normalized;
			break;
		}
		}
	}
	#endregion

	#region - Param property
	public override void updateParams (PUEXParticleSystem system)
	{
		directionX.parameterize (system);
		directionY.parameterize (system);
		directionZ.parameterize (system);
	}
	#endregion
	
	#region - Serialization
	public override JsonData save (JsonData emitterData, JsonData systemData)
	{
		JsonData ret = base.save (emitterData, systemData);

		if (directionMode == DirectionMode.DM_Add) {
			ret ["direction_mode"] = "add";
		} else if (directionMode == DirectionMode.DM_Multi) {
			ret ["direction_mode"] = "multi";
		}
		ret ["direction_x"] = PUEXUtils.serializeDynamicAttribute(directionX);
		ret ["direction_y"] = PUEXUtils.serializeDynamicAttribute(directionY);
		ret ["direction_z"] = PUEXUtils.serializeDynamicAttribute(directionZ);
		ret ["use_emitter_time"] = useEmitterTime;
		ret ["in_world_space"] = inWorldSpace;
		
		return ret;
	}
	#endregion

}
